const fs = require('fs')
const crypto = require('crypto')
const builder = require('./builder.js') // this project builder.js

const vaultname = `${builder.dirs.data}/vault.txt`
const vaultenv = 'BB_VAULT_PWD'; // require env variable setup
const vaultpwd = process.env[vaultenv]

function init() {
    if (!(vaultenv in process.env)) {
        console.log(`[ERROR]: ${vaultenv} environment variable not set`);
        process.exit(1)
    }

    var records = []
    if (fs.existsSync(vaultname)) {
        // decode read file
        records = JSON.parse(decrypt(fs.readFileSync(vaultname, 'utf-8')))
    }
    else {
        if (!fs.existsSync(builder.dirs.data))
            fs.mkdirSync(builder.dirs.data) // make data/ folder

        fs.writeFileSync(vaultname, encrypt(JSON.stringify(records)))// encode write file
    }

    return records
}

function update(records) {
    // update write file to vault.txt
    fs.writeFileSync(vaultname, encrypt(JSON.stringify(records)))
}

function encrypt(text) {
    var hash = crypto.createHash('sha256')
    hash.update(vaultpwd)
    const encryptionKey = hash.digest('hex')

    var iv = crypto.randomBytes(16)
    // create a cipher then write to `text` file
    var cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(encryptionKey, 'hex'), iv)
    var encrypted = cipher.update(text)
    encrypted = Buffer.concat([encrypted, cipher.final()])

    return iv.toString('hex') + ':' + encrypted.toString('hex')
}

function decrypt(text) {
    var hash = crypto.createHash('sha256')
    hash.update(vaultpwd)
    const encryptionKey = hash.digest('hex')

    var textParts = text.split(':') // check `xxfield: xxValue` style
    var iv = Buffer.from(textParts.shift(), 'hex')
    var encryptedText = Buffer.from(textParts.join(':'), 'hex')
    var decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(encryptionKey, 'hex'), iv)
    var decrypted = decipher.update(encryptedText)
    decrypted = Buffer.concat([decrypted, decipher.final()])

    return decrypted.toString()
}

function hashPassword(password) {
    var salt = crypto.randomBytes(16).toString('hex')
    var hash = crypto.pbkdf2Sync(password, salt, 10000, 64, 'sha512').toString('hex')

    return {salt, hash}
}

function validPassword(saveHash, savedSalt, password) {
    var hash = crypto.pbkdf2Sync(password, savedSalt, 10000, 64, 'sha512').toString('hex')
    return saveHash == hash
}

module.exports = {
    init,
    update,
    encrypt,
    decrypt,
    hashPassword,
    validPassword
}